let mut output = BuildOutput {
library_paths: Vec::new(),
library_links: Vec::new(),
+ cfgs: Vec::new(),
metadata: Vec::new(),
};
let key = format!("{}.{}", key, lib_name);
output.library_paths.extend(a.into_iter().map(|v| {
PathBuf::from(&v.0)
}));
+ } else if k == "rustc-cfg" {
+ output.cfgs.extend(a.into_iter().map(|v| v.0));
} else {
try!(config.expected("string", &k,
ConfigValue::List(a, p)));
pub library_paths: Vec<PathBuf>,
/// Names and link kinds of libraries, suitable for the `-l` flag
pub library_links: Vec<String>,
+ /// Various `--cfg` flags to pass to the compiler
+ pub cfgs: Vec<String>,
/// Metadata to pass to the immediate dependencies
pub metadata: Vec<(String, String)>,
}
pub fn parse(input: &str, pkg_name: &str) -> CargoResult<BuildOutput> {
let mut library_paths = Vec::new();
let mut library_links = Vec::new();
+ let mut cfgs = Vec::new();
let mut metadata = Vec::new();
let whence = format!("build script of `{}`", pkg_name);
whence, line)))
};
- if key == "rustc-flags" {
- let (libs, links) = try!(
- BuildOutput::parse_rustc_flags(value, &whence)
- );
- library_links.extend(links.into_iter());
- library_paths.extend(libs.into_iter());
- } else if key == "rustc-link-lib" {
- library_links.push(value.to_string());
- } else if key == "rustc-link-search" {
- library_paths.push(PathBuf::from(value));
- } else {
- metadata.push((key.to_string(), value.to_string()))
+ match key {
+ "rustc-flags" => {
+ let (libs, links) = try!(
+ BuildOutput::parse_rustc_flags(value, &whence)
+ );
+ library_links.extend(links.into_iter());
+ library_paths.extend(libs.into_iter());
+ }
+ "rustc-link-lib" => library_links.push(value.to_string()),
+ "rustc-link-search" => library_paths.push(PathBuf::from(value)),
+ "rustc-cfg" => cfgs.push(value.to_string()),
+ _ => metadata.push((key.to_string(), value.to_string())),
}
}
Ok(BuildOutput {
library_paths: library_paths,
library_links: library_links,
+ cfgs: cfgs,
metadata: metadata,
})
}
}
let value = match flags_iter.next() {
Some(v) => v,
- None => return Err(human(format!("Flag in rustc-flags has no value \
- in {}: `{}`",
+ None => return Err(human(format!("Flag in rustc-flags has no \
+ value in {}: `{}`",
whence, value)))
};
match flag {
for path in output.library_paths.iter() {
rustc.arg("-L").arg(path);
}
- if pass_l_flag && id == *current_id {
- for name in output.library_links.iter() {
- rustc.arg("-l").arg(name);
+ if id == *current_id {
+ for cfg in &output.cfgs {
+ rustc.arg("--cfg").arg(cfg);
+ }
+ if pass_l_flag {
+ for name in output.library_links.iter() {
+ rustc.arg("-l").arg(name);
+ }
}
}
}
```notrust
cargo:rustc-link-lib=static=foo
cargo:rustc-link-search=native=/path/to/foo
+cargo:rustc-cfg=foo
cargo:root=/path/to/foo
cargo:libdir=/path/to/foo/lib
cargo:include=/path/to/foo/include
```
-The `rustc-link-lib` key indicates that Cargo should pass a `-l` option to
-rustc. Similarly, `rustc-link-search` indicates that Cargo should pass a `-L`
-option.
+There are a few special keys that Cargo recognizes, affecting how the crate this
+build script is for is built:
-The `rustc-flags` key is special and indicates the flags that Cargo will
-pass to Rustc. Currently only `-l` and `-L` are accepted. Using
-`rustc-link-lib` and `rustc-link-search` is more robust.
+* `rustc-link-lib` indicates that the specified value should be passed to the
+ compiler as a `-l` flag.
+* `rustc-link-search` indicates the specified value should be passed to the
+ compiler as a `-L` flag.
+* `rustc-cfg` indicates that the specified directive will be passed as a `--cfg`
+ flag to the compiler. This is often useful for performing compile-time
+ detection of various features.
Any other element is a user-defined metadata that will be passed to
dependencies. More information about this can be found in the [`links`][links]
assert_that(p.cargo_process("build"), execs().with_status(0));
});
+
+test!(cfg_feedback {
+ let build = project("builder")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "builder"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+ "#)
+ .file("src/main.rs", "
+ #[cfg(foo)]
+ fn main() {}
+ ")
+ .file("build.rs", r#"
+ fn main() {
+ println!("cargo:rustc-cfg=foo");
+ }
+ "#);
+ assert_that(build.cargo_process("build"),
+ execs().with_status(0));
+});
+
+test!(cfg_override {
+ let (_, target) = ::cargo::ops::rustc_version().unwrap();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ links = "a"
+ build = "build.rs"
+ "#)
+ .file("src/main.rs", "
+ #[cfg(foo)]
+ fn main() {}
+ ")
+ .file("build.rs", "")
+ .file(".cargo/config", &format!(r#"
+ [target.{}.a]
+ rustc-cfg = ["foo"]
+ "#, target));
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0));
+});